﻿using System;
using System.IO;

using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using FileHelpers;
using LumenWorks;
using System.Xml.Serialization;

namespace Zone4SI
{
    public partial class Form1 : Form
    {
        Dictionary<string, string> m_classes;     // Is created by reading the class CSV
        List<int> m_rentals; // Is created by reading the DibblerRentals CSV
        PerClass[] m_pc;
        List<string> m_clubs;
        bool m_ChaseSprint;
        int m_numRaces;

        #region Race Dependent Data that is currently stored in the settings file
        int rdd_StartingBibNumber;
//        string rdd_InputFilename;
        #endregion

        string RaceName;        // This is an XML filename spec

        public Form1()
        {
            RaceName = "";
            m_classes = new Dictionary<string, string>();
            m_rentals = new List<int>();
            InitializeComponent();
            m_pc = new PerClass[6];
            for (int i = 0; i < 6; i++)
                m_pc[0] = new PerClass();

            m_clubs = new List<string>();

            System.Reflection.Assembly a = System.Reflection.Assembly.GetExecutingAssembly();
            Version v = a.GetName().Version;
            tsLabel1.Text = v.ToString();
        }

        private void ShowRaceBoxes()
        {
            m_numRaces = cbNumberRaces.SelectedIndex + 1;
            if (cbNumberRaces.SelectedIndex == 0)
            {
                chkChaseSprint.Visible = false;
            }
            else
            {
///                chkChaseSprint.Visible = true;
            }

            if (chkChaseSprint.Visible == true && chkChaseSprint.Checked == true)
            {
                m_ChaseSprint = true;
                m_numRaces--;
            }

            label17.Visible =
            tbClass6Index.Visible = (m_numRaces  ==  6);
            label16.Visible =
            tbClass5Index.Visible = (m_numRaces >= 5);
            label15.Visible =
            tbClass4Index.Visible = (m_numRaces >= 4);
            label14.Visible =
            tbClass3Index.Visible = (m_numRaces >= 3);
            label13.Visible =
            tbClass2Index.Visible = (m_numRaces >= 2);

        }
        private void FillTextActionFields(ComboBox cbActionField)
        {
            cbActionField.Items.Add("- Output text field always empty - ");
            cbActionField.Items.Add("Convert 'Yes' to an asterisk");
            cbActionField.Items.Add("Copy field contents");
    }

        // The values are cast in stone, as they are saved in the race info files (Z4SI)
        enum RaceFormat
        {
            Simple = 0,
            Farsta = 1,     // not yet implemented
            Team = 2,       // NOT YET IMPLEMENTED
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (global::Zone4SI.Properties.Settings.Default.RecentFiles == null)
            {
                global::Zone4SI.Properties.Settings.Default.RecentFiles = new System.Collections.Specialized.StringCollection();
                global::Zone4SI.Properties.Settings.Default.Save();
            }

            UpdateMenu();

            // Make sure the items here match the enum 'RaceFormat'
            cbRaceFormat.Items.Add("Simple (OE/MT)");
            //            cbRaceFormat.Items.Add("Farsta");
            //            cbRaceFormat.Items.Add("Team");

            cbRaceFormat.SelectedIndex = 0;

            cbNumberRaces.Items.Add(1);
            cbNumberRaces.Items.Add(2);
            cbNumberRaces.Items.Add(3);
            cbNumberRaces.Items.Add(4);
            cbNumberRaces.Items.Add(5);
            cbNumberRaces.Items.Add(6);


            FillTextActionFields(cbText1Action);
            FillTextActionFields(cbText2Action);
            FillTextActionFields(cbText3Action);

            cbNumberRaces.SelectedIndex = 0;

            ShowRaceBoxes();
        }
        private void ClearData()
        {
            cbNumberRaces.SelectedIndex = 0;
            chkChaseSprint.Checked = false;
            cbRaceFormat.SelectedIndex = 0;
            ShowRaceBoxes();
            chkClubAbbrev.Checked = false;
            chkCountryAbbrev.Checked = false;
            tbInputFile.Text = "";
            tbClassFile.Text = "";
            tbOutputFile.Text = "";
            tbRentalFile.Text = "";

            tbFirstnameIndex.Text = "";
            tbSurnameIndex.Text = "";
            tbGenderIndex.Text = "";
            tbCountryIndex.Text = "";
            tbSICardIndex.Text = "";
            tbClubIndex.Text = "";
            tbYearBornIndex.Text = "";
            rdd_StartingBibNumber = 0;
            tbClass1Index.Text = "";
            tbClass2Index.Text = "";
            tbClass3Index.Text = "";
            tbClass4Index.Text = "";
            tbClass5Index.Text = "";
            tbClass6Index.Text = "";

            tbText1Index.Text = "";
            tbText2Index.Text = "";
            tbText3Index.Text = "";

            cbText1Action.SelectedIndex = 0;
            cbText2Action.SelectedIndex = 0;
            cbText3Action.SelectedIndex = 0;
        }
        private void LoadData(string name)
        {
            this.Text = "Zone4SI -- " + name;
            RaceName = name;

            RaceData r = RaceData.Load(name);
            cbNumberRaces.SelectedIndex = r.NumberRaces - 1;
            chkChaseSprint.Checked = r.ChaseSprint;
            cbRaceFormat.SelectedIndex = r.RaceFormat;

            ShowRaceBoxes();

            chkClubAbbrev.Checked = r.ExtractClubAbbrev;
            chkCountryAbbrev.Checked = r.ExtractCountryAbbrev;
            tbInputFile.Text = r.DataFile;
            tbClassFile.Text = r.ClassFile;
            tbOutputFile.Text = r.OutputFile;
            tbRentalFile.Text = r.RentalsFile;

            tbFirstnameIndex.Text = r.Firstname;
            tbSurnameIndex.Text = r.Surname;
            tbGenderIndex.Text = r.Gender;
            tbCountryIndex.Text = r.Country;
            tbSICardIndex.Text = r.SICard;
            tbClubIndex.Text = r.Club;
            tbYearBornIndex.Text = r.YearBorn;
            rdd_StartingBibNumber = r.FirstBib;

            tbClass1Index.Text = r.Race1;
            tbClass2Index.Text = r.Race2;
            tbClass3Index.Text = r.Race3;
            tbClass4Index.Text = r.Race4;
            tbClass5Index.Text = r.Race5;
            tbClass6Index.Text = r.Race6;

            tbText1Index.Text = r.Text1;
            tbText2Index.Text = r.Text2;
            tbText3Index.Text = r.Text3;

            cbText1Action.SelectedIndex = (int) r.Text1Action;
            cbText2Action.SelectedIndex = (int) r.Text2Action;
            cbText3Action.SelectedIndex = (int) r.Text3Action;

            VerifyAllFields(null, null);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // clear the error window
            listBox1.Items.Clear();
            

            // First thing read in the class list
            try
            {
                char Delimiter = ',';
                if (System.IO.Path.GetExtension(tbClassFile.Text).ToUpper() == ".TAB")
                {
                    Delimiter = '\t';
                }

                LumenWorks.Framework.IO.Csv.CsvReader r = new LumenWorks.Framework.IO.Csv.CsvReader(new System.IO.StreamReader(tbClassFile.Text, Encoding.GetEncoding("Windows-1252")), true, Delimiter);
                r.SkipEmptyLines = true;
                
                m_classes.Clear();
                
                while (r.ReadNextRecord())
                {
                    m_classes.Add(r[1], r[2]);
                }
                System.Diagnostics.Debug.WriteLine("HH");
            }
            catch (Exception ex)
            {
                listBox1.Items.Add("Error reading class file: " + ex.Message);
                listBox1.Items.Add("   At least three columns are expected in this file:");
                listBox1.Items.Add("   The second must be the short class name, and ");
                listBox1.Items.Add("   the third must be the long class name.  ");
                listBox1.Items.Add("   All other columns are ignored.");
                listBox1.Items.Add("   The first row is ignored for headers.");
                return;
            }

            // Next read the rentals list
            if (tbRentalFile.Text.Trim().Length > 0)
            {
                try
                {
                    char Delimiter = ',';
                    if (System.IO.Path.GetExtension(tbRentalFile.Text).ToUpper() == ".TAB")
                    {
                        Delimiter = '\t';
                    }
                    LumenWorks.Framework.IO.Csv.CsvReader r = new LumenWorks.Framework.IO.Csv.CsvReader(new System.IO.StreamReader(tbRentalFile.Text), true, Delimiter);
                    r.SkipEmptyLines = true;
                    m_rentals.Clear();
                    while (r.ReadNextRecord())
                    {
                        m_rentals.Add(int.Parse(r[0]));
                    }
                }
                catch (Exception ex)
                {
                    listBox1.Items.Add("Error reading rentals file: " + ex.Message);
                    listBox1.Items.Add("  This file must have at least one column.  The first column");
                    listBox1.Items.Add("   must contain the SI number of the finger stick available");
                    listBox1.Items.Add("   to be rented.");
                    listBox1.Items.Add("  The first row is ignored for headers.");
                    return;
                }
            }

            // Next check if the last column is "BibNumber"
            try
            {
                char Delimiter = ',';
                if (System.IO.Path.GetExtension(tbInputFile.Text).ToUpper() == ".TAB")
                {
                    Delimiter = '\t';
                }

                System.IO.StreamReader input_strm = new System.IO.StreamReader(tbInputFile.Text, Encoding.GetEncoding("Windows-1252"), true);
                LumenWorks.Framework.IO.Csv.CsvReader csvr = new LumenWorks.Framework.IO.Csv.CsvReader(input_strm, true, Delimiter);
                csvr.SkipEmptyLines = true;
                if (!csvr.ReadNextRecord())
                {
                    listBox1.Items.Add("Input file seems to have no data in it.");
                }
                else
                {
                    string [] headers = csvr.GetFieldHeaders();
                    if (headers[csvr.FieldCount - 1].ToUpperInvariant() != "BIBNUMBER")
                    {
                        AssignBibs ab = new AssignBibs();
                        ab.BibNumber = rdd_StartingBibNumber;
                        if (ab.ShowDialog() != System.Windows.Forms.DialogResult.OK)
                            return;

                        
                        int bibs = 
                        rdd_StartingBibNumber = ab.BibNumber;
                        csvr.Dispose();
                        input_strm.Close();
                        input_strm.Dispose();
                        string backup_name = tbInputFile.Text + ".bak";
                        System.IO.File.Copy(tbInputFile.Text, backup_name);
                        input_strm = new System.IO.StreamReader(backup_name, Encoding.GetEncoding("Windows-1252"), true);
                        csvr = new LumenWorks.Framework.IO.Csv.CsvReader(input_strm, true, Delimiter);
                        csvr.SkipEmptyLines = true;
                        System.IO.StreamWriter output_strm = new System.IO.StreamWriter(tbInputFile.Text, false, Encoding.GetEncoding("Windows-1252"), 1024);
                        int line_counter = 0;
                        while (csvr.ReadNextRecord())
                        {
                            if (line_counter == 0)
                            {
                                for (int i = 0; i < csvr.FieldCount; i++)
                                {
                                    if (headers[i].Length > 0)
                                    {
                                        if (headers[i].IndexOf(csvr.Delimiter) >= 0)
                                        {
                                            output_strm.Write(csvr.Quote);
                                            output_strm.Write(headers[i]);
                                            output_strm.Write(csvr.Quote);
                                        }
                                        else
                                            output_strm.Write(headers[i]);
                                        output_strm.Write(csvr.Delimiter);
                                    }
                                }
                                output_strm.WriteLine("BibNumber");
                            }

                            for (int i = 0; i < csvr.FieldCount; i++)
                            {
                                if (headers[i].Length > 0)
                                {
                                    if (csvr[i].IndexOf(csvr.Delimiter) >= 0)
                                    {
                                        output_strm.Write(csvr.Quote);
                                        output_strm.Write(csvr[i]);
                                        output_strm.Write(csvr.Quote);
                                    }
                                    else
                                        output_strm.Write(csvr[i]);
                                    output_strm.Write(csvr.Delimiter);
                                }
                            }
                            output_strm.WriteLine((bibs++).ToString());
                            line_counter++;
                        }
                        output_strm.Close();
                        output_strm.Dispose();
                        csvr.Dispose();
                        input_strm.Close();
                        input_strm.Dispose();
                    }
                    
                }
            }
            catch (Exception ex)
            {
                listBox1.Items.Add("Input file cannot be opened.  Error msg: " + ex.Message);
                return;
            }


            if (System.IO.File.Exists(tbOutputFile.Text) && MessageBox.Show(System.String.Format("{0} already exists.  Overwrite?", tbOutputFile.Text), "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.No)
                return;

            try
            {
                int line_counter = 0;
                int people_counter = 0;
                int specials_counter = 0;
                List<SPORTSoftwareData> z4d = new List<SPORTSoftwareData>();
                SPORTSoftwareData rec;
                if (cbRaceFormat.SelectedIndex == (int)RaceFormat.Farsta)
                    rec = new OS2003_Data();
                else
                {
                    if (cbNumberRaces.SelectedIndex > 0)
                        rec = new MT2003_Data();
                    else
                        rec = new OE2003_Data();
                }
                rec.CreateHeader();
                z4d.Add(rec);

                char Delimiter = ',';
                if (System.IO.Path.GetExtension(tbInputFile.Text).ToUpper() == ".TAB")
                {
                    Delimiter = '\t';
                }

                LumenWorks.Framework.IO.Csv.CsvReader csvr = new LumenWorks.Framework.IO.Csv.CsvReader(new System.IO.StreamReader(tbInputFile.Text, Encoding.GetEncoding("Windows-1252"), true), true, Delimiter);
                csvr.SkipEmptyLines = true;
                while (csvr.ReadNextRecord())
                {
                    line_counter++;
                    string lastname = csvr[int.Parse(tbSurnameIndex.Text) - 1];
                    string firstname = csvr[int.Parse(tbFirstnameIndex.Text) - 1];

                    m_pc[0].active = true;
                    string classname = csvr[int.Parse(tbClass1Index.Text) - 1];
                    if (classname.Trim().Length > 0)
                    {
                        string shortname;
                        if (m_classes.TryGetValue(classname, out shortname) == false)
//                        Zone4class cls = findClass(classname);
//                        if (cls == null)
                        {
                            listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                            continue;
                        }
                        m_pc[0].shortClassName = classname;
                        m_pc[0].participating = true;
                    }
                    else
                        m_pc[0].participating = false;

                    if (cbNumberRaces.SelectedIndex > 0)
                    {
                        m_pc[1].active = true;
                        classname = csvr[int.Parse(tbClass2Index.Text) - 1];
                        if (classname.Trim().Length > 0)
                        {
                            string shortname;
                            if (m_classes.TryGetValue(classname, out shortname) == false)
//                            Zone4class cls = findClass(classname);
  //                          if (cls == null)
                            {
                                listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                                continue;
                            }
                            m_pc[1].shortClassName = classname;     // cls.ShortName;
                            m_pc[1].participating = true;
                        }
                        else
                            m_pc[1].participating = false;
                    }
                    else
                        m_pc[1].active = false;

                    if (cbNumberRaces.SelectedIndex > 1)
                    {
                        m_pc[2].active = true;
                        classname = csvr[int.Parse(tbClass3Index.Text) - 1];
                        if (classname.Trim().Length > 0)
                        {
                            string shortname;
                            if (m_classes.TryGetValue(classname, out shortname) == false)

//                            Zone4class cls = findClass(classname);
  //                          if (cls == null)
                            {
                                listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                                continue;
                            }
                            m_pc[2].shortClassName = classname; //cls.ShortName;
                            m_pc[2].participating = true;
                        }
                        else
                            m_pc[2].participating = false;
                    }
                    else
                        m_pc[2].active = false;

                    if (cbNumberRaces.SelectedIndex > 2)
                    {
                        m_pc[3].active = true;
                        classname = csvr[int.Parse(tbClass4Index.Text) - 1];
                        if (classname.Trim().Length > 0)
                        {
                            string shortname;
                            if (m_classes.TryGetValue(classname, out shortname) == false)
//                            Zone4class cls = findClass(classname);
  //                          if (cls == null)
                            {
                                listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                                continue;
                            }
                            m_pc[3].shortClassName = classname; // cls.ShortName;
                            m_pc[3].participating = true;
                        }
                        else
                            m_pc[3].participating = false;
                    }
                    else
                        m_pc[3].active = false;

                    if (cbNumberRaces.SelectedIndex > 3)
                    {
                        m_pc[4].active = true;
                        classname = csvr[int.Parse(tbClass5Index.Text) - 1];
                        if (classname.Trim().Length > 0)
                        {
                            string shortname;
                            if (m_classes.TryGetValue(classname, out shortname) == false)
//                            Zone4class cls = findClass(classname);
  //                          if (cls == null)
                            {
                                listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                                continue;
                            }
                            m_pc[4].shortClassName = classname;// cls.ShortName;
                            m_pc[4].participating = true;
                        }
                        else
                            m_pc[4].participating = false;
                    }
                    else
                        m_pc[4].active = false;

                    if (cbNumberRaces.SelectedIndex > 4)
                    {
                        m_pc[5].active = true;
                        classname = csvr[int.Parse(tbClass6Index.Text) - 1];
                        if (classname.Trim().Length > 0)
                        {
                            string shortname;
                            if (m_classes.TryGetValue(classname, out shortname) == false)

//                            Zone4class cls = findClass(classname);
  //                          if (cls == null)
                            {
                                listBox1.Items.Add(String.Format("Couldn't find class '{2}' for participant '{0}, {1}'", lastname, firstname, classname));
                                continue;
                            }
                            m_pc[5].shortClassName = classname; // cls.ShortName;
                            m_pc[5].participating = true;
                        }
                        else
                            m_pc[5].participating = false;
                    }
                    else
                        m_pc[5].active = false;
                    //
                    // do the text fields
                    string text1 = GetTextField(tbText1Index, cbText1Action, csvr);
                    string text2 = GetTextField(tbText2Index, cbText2Action, csvr);
                    string text3 = GetTextField(tbText3Index, cbText3Action, csvr);

                    int bibno = int.Parse(csvr["BibNumber"]);

                    int bib_adjuster = 0;
                    for (int j = 0; j < 6; j++)
                    {
                        string base_class = "";
                        int si_issues = 0;
                        for (int i = 0; i < 6; i++)
                        {
                            if (m_pc[i].participating)
                            {
                                if (base_class.Length == 0)
                                {
                                    int clubno;
                                    string maybecountry;
                                    string clubname = GetClubInfo(csvr[int.Parse(tbClubIndex.Text) - 1], out clubno, out maybecountry);
                                    string countryname = tbCountryIndex.Text.Length == 0 ? maybecountry : GetCountry(csvr[int.Parse(tbCountryIndex.Text) - 1]);
                                    base_class = m_pc[i].shortClassName;
                                    rec = (cbRaceFormat.SelectedIndex == (int) RaceFormat.Farsta) ? (SPORTSoftwareData)new OS2003_Data() : ((cbNumberRaces.SelectedIndex == 0) ? (SPORTSoftwareData)new OE2003_Data() : (SPORTSoftwareData)new MT2003_Data());
                                    rec.LoadBasics(bibno + bib_adjuster,
                                                   firstname,
                                                   lastname,
                                                   csvr[int.Parse(tbGenderIndex.Text) - 1],
                                                   countryname,
                                                   clubno,
                                                   clubname,
                                                   csvr[int.Parse(tbYearBornIndex.Text) - 1],
                                                   text1,
                                                   text2,
                                                   text3);
                                    rec.Short = base_class;
//                                    listBox1.Items.Add(String.Format("Lastname = {0}", csvr[int.Parse(textBox5.Text) - 1]));

                                }
                                if (base_class == m_pc[i].shortClassName)
                                {
                                    string sicard = csvr[int.Parse(tbSICardIndex.Text) - 1];
                                    bool rent = false;
                                    try
                                    {
                                        rent = IsRental(sicard);
                                    }
                                    catch (Exception)
                                    {
                                        listBox1.Items.Add(String.Format("The SICard number for user {0} {1} is badly formed", firstname, lastname));
                                    }
                                    if (sicard.Trim().Length == 0)
                                    {
                                        si_issues++;
                                    }
                                    rec.LoadSpecifics(i, sicard, "X", rent);
                                    m_pc[i].participating = false;  // done
                                }
                            }
                        }
                        if (base_class.Length > 0)
                        {
                            if (bib_adjuster == 0)
                                people_counter++;
                            else
                                specials_counter++;

                            z4d.Add(rec);
                            bib_adjuster += 1000;
                        }
                        if (si_issues > 0)
                            listBox1.Items.Add(String.Format("User {0} {1} does not have an SI number", firstname, lastname));
                    }
                    System.Diagnostics.Debug.WriteLine("HH");
                    bibno++;
                }
                csvr.Dispose();

                listBox1.Items.Add(String.Format("Processed {0} input records", line_counter));
                listBox1.Items.Add(String.Format("Created {0} unique participant records", people_counter));
                listBox1.Items.Add(String.Format("    and {0} duplicate participants", specials_counter));
//                MT2003_Data[] z4d_array = z4d.ToArray();


                if (cbRaceFormat.SelectedIndex == (int)RaceFormat.Farsta)
                {
                    FileHelperEngine<OS2003_Data> engine = new FileHelperEngine<OS2003_Data>();
                    List<OS2003_Data> data = new List<OS2003_Data>();
                    foreach (SPORTSoftwareData d in z4d)
                    {
                        data.Add(d as OS2003_Data);
                    }
                    engine.WriteFile(tbOutputFile.Text, data);
                }
                else
                {
                    if (cbNumberRaces.SelectedIndex == 0)
                    {
                        FileHelperEngine<OE2003_Data> engine = new FileHelperEngine<OE2003_Data>(Encoding.GetEncoding("Windows-1252"));
                        List<OE2003_Data> data = new List<OE2003_Data>();
                        foreach (SPORTSoftwareData d in z4d)
                        {
                            data.Add(d as OE2003_Data);
                        }
                        engine.WriteFile(tbOutputFile.Text, data);
                    }
                    else
                    {
                        FileHelperEngine<MT2003_Data> engine = new FileHelperEngine<MT2003_Data>();
                        List<MT2003_Data> data = new List<MT2003_Data>();
                        foreach (SPORTSoftwareData d in z4d)
                        {
                            data.Add(d as MT2003_Data);
                        }
                        engine.WriteFile(tbOutputFile.Text, data);
                    }
                }
                System.Diagnostics.Debug.WriteLine("HH");
            }
            catch (Exception ex)
            {
                listBox1.Items.Add("Error: " + ex.Message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="textfield"></param>
        /// <param name="action"></param>
        /// <param name="csvr"></param>
        /// <returns></returns>
        string GetTextField(TextBox textfield, ComboBox action, LumenWorks.Framework.IO.Csv.CsvReader csvr)
        {
            string text = "";


            switch (action.SelectedIndex)
            {
                case 1:
                    text = (textfield.Text.Trim().Length > 0) ? ((csvr[int.Parse(textfield.Text) - 1] == "Yes") ? "*" : "") : "";
                    break;

                case 2:
                    text = (textfield.Text.Trim().Length > 0) ? csvr[int.Parse(textfield.Text) - 1] : "";
                    break;
            }
            return text;
        }

        string GetCountry(string country)
        {
            if (chkCountryAbbrev.Checked == true)
            {
                System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@".*\((.*)\).*");
                System.Text.RegularExpressions.Match m = r.Match(country);
                if (m.Success && m.Groups.Count > 1)
                {
                    country = m.Groups[1].Value;
                }
            }
            return country;
        }
        /// <summary>
        /// Extract club number, club name and club's nationality, based on club string from Zone4
        /// </summary>
        /// <param name="club"></param>
        /// <param name="clubno"></param>
        /// <param name="countryname">if the country index is blank and a country was found in the club's abbreviation, then country is returned.</param>
        /// <returns>Club name, might be just abbreviation</returns>
        string GetClubInfo(string club, out int clubno, out string countryname)
        {
            countryname = "";
            if (chkClubAbbrev.Checked == true)
            {
                System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(@".*\(([^/]*)(?:/(.*))?\).*");
                System.Text.RegularExpressions.Match m = r.Match(club);
                if (m.Success && m.Groups.Count > 1)
                {
                    club = m.Groups[1].Value;
                    if (tbCountryIndex.Text.Trim() == "")
                    {
                        if (m.Groups.Count > 2  &&  m.Groups[2].Value.Trim().Length > 0)
                            countryname = m.Groups[2].Value;
                        else
                            countryname = "CAN";
                    }
                }
            }

            if (club == "")
            {
                club = "---";
                countryname = "---";
            }

            for (int i = 0; i < m_clubs.Count; i++)
            {
                if (m_clubs[i] == club)
                {
                    clubno = i + 1;
                    return m_clubs[i];
                }
            }
            m_clubs.Add(club);
            clubno = m_clubs.Count;
            
            return club;
        }

        private bool IsRental(string sicard)
        {
            if (m_rentals.Count == 0 || sicard.Trim().Length == 0)
                return false;
            int sicardnum = int.Parse(sicard.Trim());
            if (m_rentals.Find(b => b == sicardnum) != 0)
                return true;
            return false;
        }
#if JUNK
        private Zone4class findClass(string text)
        {
            foreach (Zone4class cls in m_classes)
            {
                if (cls.LongName == text)
                    return cls;
            }
            return null;
        }
#endif
        private void VerifyAllFields(object sender, EventArgs e)
        {
            int val;
            chkCountryAbbrev.Enabled = (this.tbCountryIndex.Text.Trim().Length > 0);

            if (int.TryParse(this.tbSurnameIndex.Text, out val) == false
                || int.TryParse(this.tbFirstnameIndex.Text, out val) == false
                || int.TryParse(this.tbGenderIndex.Text, out val) == false
                || (this.tbCountryIndex.Text.Trim().Length > 0 
                    && int.TryParse(this.tbCountryIndex.Text, out val) == false)
                || int.TryParse(this.tbSICardIndex.Text, out val) == false
                || int.TryParse(this.tbClubIndex.Text, out val) == false
                || int.TryParse(this.tbYearBornIndex.Text, out val) == false
                || int.TryParse(this.tbClass1Index.Text, out val) == false
                || (tbText1Index.Text.Trim().Length > 0 
                    && int.TryParse(this.tbText1Index.Text, out val) == false)
                || (tbText2Index.Text.Trim().Length > 0
                    && int.TryParse(this.tbText2Index.Text, out val) == false)
                || (tbText3Index.Text.Trim().Length > 0
                    && int.TryParse(this.tbText3Index.Text, out val) == false)
                || tbInputFile.Text.Trim().Length == 0
                || tbOutputFile.Text.Trim().Length == 0
                || tbClassFile.Text.Trim().Length == 0)
            {
                btnConvert.Enabled = false;
                return;
            }
            if (m_numRaces > 5)
                if (int.TryParse(this.tbClass6Index.Text, out val) == false)
                {
                    btnConvert.Enabled = false;
                    return;
                }
            if (m_numRaces > 4)
                if (int.TryParse(this.tbClass5Index.Text, out val) == false)
                {
                    btnConvert.Enabled = false;
                    return;
                }
            if (m_numRaces > 3)
                if (int.TryParse(this.tbClass4Index.Text, out val) == false)
                {
                    btnConvert.Enabled = false;
                    return;
                }
            if (m_numRaces > 2)
                if (int.TryParse(this.tbClass3Index.Text, out val) == false
                    || (this.tbText3Index.Text.Trim().Length > 0 
                        && int.TryParse(this.tbText3Index.Text, out val) == false))
                {
                    btnConvert.Enabled = false;
                    return;
                }
            if (m_numRaces > 1)
                if (int.TryParse(this.tbClass2Index.Text, out val) == false
                    || (this.tbText2Index.Text.Trim().Length > 0
                        && int.TryParse(this.tbText2Index.Text, out val) == false))
                {
                    btnConvert.Enabled = false;
                    return;
                }
            btnConvert.Enabled = true;
            return;
        }

        private void cbNumRaces_SelectedIndexChanged(object sender, EventArgs e)
        {
            ShowRaceBoxes();
            VerifyAllFields(null, null);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
        }
        private void SaveData(string name)
        {
            try
            {
                RaceData r = new RaceData();
                r.ExtractClubAbbrev = chkClubAbbrev.Checked;
                r.ExtractCountryAbbrev = chkCountryAbbrev.Checked;
                r.DataFile = tbInputFile.Text;
                r.ClassFile = tbClassFile.Text;
                r.OutputFile = tbOutputFile.Text;
                r.RentalsFile = tbRentalFile.Text;

                r.Firstname = tbFirstnameIndex.Text;
                r.Surname = tbSurnameIndex.Text;
                r.Gender = tbGenderIndex.Text;
                r.Country = tbCountryIndex.Text;
                r.SICard = tbSICardIndex.Text;
                r.Club = tbClubIndex.Text;
                r.YearBorn = tbYearBornIndex.Text;

                r.FirstBib = rdd_StartingBibNumber;
                r.Race1 = tbClass1Index.Text;
                r.Race2 = tbClass2Index.Text;
                r.Race3 = tbClass3Index.Text;
                r.Race4 = tbClass4Index.Text;
                r.Race5 = tbClass5Index.Text;
                r.Race6 = tbClass6Index.Text;
                r.NumberRaces = cbNumberRaces.SelectedIndex + 1;

                r.Text1 = tbText1Index.Text;
                r.Text1Action = (RaceData.TextAction) cbText1Action.SelectedIndex;
                r.Text2 = tbText2Index.Text;
                r.Text2Action = (RaceData.TextAction)cbText2Action.SelectedIndex;
                r.Text3 = tbText3Index.Text;
                r.Text3Action = (RaceData.TextAction)cbText3Action.SelectedIndex;

                r.ChaseSprint = m_ChaseSprint;
                r.RaceFormat = cbRaceFormat.SelectedIndex;

                r.Save(name);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            FileDialog fld = new OpenFileDialog();
            fld.Filter = "CSV files (*.CSV)|*.CSV|TAB files (*.TAB)|*.TAB|All files (*.*)|*.*";
            fld.FilterIndex = 1;
            fld.InitialDirectory = tbInputFile.Text;
            fld.RestoreDirectory = true;
            if (fld.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                tbInputFile.Text = fld.FileName;

        }

        private void button3_Click(object sender, EventArgs e)
        {
            FileDialog fld = new OpenFileDialog();
            fld.Filter = "CSV files (*.CSV)|*.CSV|TAB files (*.TAB)|*.TAB|All files (*.*)|*.*";
            fld.FilterIndex = 1;
            fld.InitialDirectory = tbClassFile.Text;
            fld.RestoreDirectory = true;
            if (fld.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                tbClassFile.Text = fld.FileName;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            SaveFileDialog fld = new SaveFileDialog();
            fld.Filter = "CSV files (*.CSV)|*.CSV|All files (*.*)|*.*";
            fld.FilterIndex = 1;
            fld.InitialDirectory = tbOutputFile.Text;
            fld.RestoreDirectory = true;
            fld.OverwritePrompt = false;
            if (fld.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                tbOutputFile.Text = fld.FileName;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            FileDialog fld = new OpenFileDialog();
            fld.Filter = "CSV files (*.CSV)|*.CSV|TAB files (*.TAB)|*.TAB|All files (*.*)|*.*";
            fld.FilterIndex = 1;
            fld.InitialDirectory = this.tbRentalFile.Text;
            fld.RestoreDirectory = true;
            if (fld.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                tbRentalFile.Text = fld.FileName;
        }
        #region Menu Items
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ClearData();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void aboutMenuItem_Click(object sender, EventArgs e)
        {
            About a = new About();
            a.ShowDialog();
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.AddExtension = true;
            sfd.AutoUpgradeEnabled = true;
            sfd.FileName = RaceName;
            sfd.Filter = "Z4SI files (*.Z4SI)|*.z4si|All files (*.*)|*.*";
            sfd.FilterIndex = 1;
            if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                RaceName = sfd.FileName;
                this.Text = "Zone4SI -- " + sfd.FileName;
                SaveData(sfd.FileName);
                MostRecentlyUsed(sfd.FileName);
            }
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.AddExtension = true;
            ofd.AutoUpgradeEnabled = true;
            ofd.FileName = RaceName;
            ofd.Filter = "Z4SI files (*.Z4SI)|*.z4si|All files (*.*)|*.*";
            ofd.FilterIndex = 1;
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                LoadData(ofd.FileName);
                MostRecentlyUsed(ofd.FileName);
            }
        }

        private void MostRecentlyUsed(string fn)
        {
            int found = -1;
            int count = global::Zone4SI.Properties.Settings.Default.RecentFiles.Count;
            string[] RecentFiles = new string[count];
            global::Zone4SI.Properties.Settings.Default.RecentFiles.CopyTo(RecentFiles, 0);
            int i;
            for (i = 0; i < count; i++)
            {
                if (String.Compare(fn, RecentFiles[i], true) == 0)
                {
                    found = i;
                    break;
                }
            }

            switch (found)
            {
                case -1:
                    global::Zone4SI.Properties.Settings.Default.RecentFiles.Insert(0, fn);
                    break;
                case 0:
                    break;
                default:
                    global::Zone4SI.Properties.Settings.Default.RecentFiles.RemoveAt(found);
                    global::Zone4SI.Properties.Settings.Default.RecentFiles.Insert(0, fn);
                    break;
            }
            if (global::Zone4SI.Properties.Settings.Default.RecentFiles.Count > 10)
                global::Zone4SI.Properties.Settings.Default.RecentFiles.RemoveAt(10);

            global::Zone4SI.Properties.Settings.Default.Save();

            UpdateMenu();
        }

        void UpdateMenu()
        {

            ToolStripMenuItem x = this.raceMenuItem;
            while (x.DropDown.Items.Count > 6)
            {
                x.DropDownItems.RemoveAt(5);
            }
            int i = 1;
            if (global::Zone4SI.Properties.Settings.Default.RecentFiles != null)
            {
                foreach (string s in global::Zone4SI.Properties.Settings.Default.RecentFiles)
                {
                    ToolStripMenuItem tsmi = new ToolStripMenuItem(String.Format("{0} - {1}", i, s), null, recentToolStripMenuItem_Click);
                    tsmi.Tag = i-1;
                    x.DropDownItems.Insert(i + 4, tsmi);
                    i++;
                }
                x.DropDownItems.Insert(i + 4, new ToolStripSeparator());
            }
            System.Diagnostics.Trace.Write("FSDS");
        }

        private void recentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripDropDownItem x = (ToolStripDropDownItem)sender;
            string s = global::Zone4SI.Properties.Settings.Default.RecentFiles[(int) x.Tag];
            if (System.IO.File.Exists(s))
            {
                LoadData(s);
                MostRecentlyUsed(s);
            }
            else
            {
                MessageBox.Show(String.Format("Item {0} does not exist and has been removed from the Recently Used List", s));
                global::Zone4SI.Properties.Settings.Default.RecentFiles.RemoveAt((int)x.Tag);
                UpdateMenu();
            }

        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (RaceName.Length > 0)
                SaveData(RaceName);
            else
                saveAsToolStripMenuItem_Click(sender, e);

        }
        #endregion

        private void cbChaseSprint_CheckedChanged(object sender, EventArgs e)
        {
            ShowRaceBoxes();
        }


        private void cbRaceFormat_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cbRaceFormat.SelectedIndex == (int)RaceFormat.Farsta)
            {
                cbNumberRaces.SelectedIndex = 0;
                cbNumberRaces.Enabled = false;
            }
            else
                cbNumberRaces.Enabled = true;

            ShowRaceBoxes();
        }

    }

    [DelimitedRecord(",")]
    abstract class SPORTSoftwareData
    {
        public abstract void CreateHeader();
        public abstract void LoadBasics(int bibno, string firstname, string surname, string gender, string country, int clubno, string clubname, string YOB, string ltext1, string ltext2, string ltext3);
        public abstract void LoadSpecifics(int offset, string sicard, string e, bool rental);
        public abstract string Short { get; set; }
    }


    [DelimitedRecord(",")]
    class OS2003_Data : SPORTSoftwareData
    {
        public string Stno;
        public string Descr;
        public string Block;
        public string nc;
        public string Start;
        public string Time;
        public string Classifier;
        public string Club_no;
        public string Cl_name;
        public string City;
        public string Nat;
        public string Cl_no;
        public string _short;
        public string Long;
        public string Legs;
        public string Num1;
        public string Num2;
        public string Num3;
        public string Text1;
        public string Text2;
        public string Text3;
        public string Start_fee;
        public string Paid;

        public string Surname1;
        public string First_name1;
        public string YB1;
        public string S1;
        public string Start1;
        public string Finish1;
        public string Time1;
        public string Classifier1;
        public string Chip1;
        public string Rented1;
        public string Database_Id1;

        public string Surname2;
        public string First_name2;
        public string YB2;
        public string S2;
        public string Start2;
        public string Finish2;
        public string Time2;
        public string Classifier2;
        public string Chip2;
        public string Rented2;
        public string Database_Id2;

        public string Surname3;
        public string First_name3;
        public string YB3;
        public string S3;
        public string Start3;
        public string Finish3;
        public string Time3;
        public string Classifier3;
        public string Chip3;
        public string Rented3;
        public string Database_Id3;
        public string dummy;

        public override void CreateHeader()
        {
            Stno = "Stno";
            Descr = "Descr";
            Block = "Block";
            nc = "nc";
            Start = "Start";
            Time = "Time";
            Classifier = "Classifier";
            Club_no = "Club no.";
            Cl_name = "Cl.name";
            City = "City";
            Nat = "Nat";
            Cl_no = "Cl. no.";
            _short = "Short";
            Long = "Long";
            Legs = "Legs";
            Num1 = "Num1";
            Num2 = "Num2";
            Num3 = "Num3";
            Text1 = "Text1";
            Text2 = "Text2";
            Text3 = "Text3";
            Start_fee = "Start fee";
            Paid = "Paid";

            Surname1 = "Surname";
            First_name1 = "First name";
            YB1 = "YB";
            S1 = "S";
            Start1 = "Start";
            Finish1 = "Finish";
            Time1 = "Time";
            Classifier1 = "Classifier";
            Chip1 = "Chip";
            Rented1 = "Rented";
            Database_Id1 = "Database Id";

            Surname2 = "Surname";
            First_name2 = "First name";
            YB2 = "YB";
            S2 = "S";
            Start2 = "Start";
            Finish2 = "Finish";
            Time2 = "Time";
            Classifier2 = "Classifier";
            Chip2 = "Chip";
            Rented2 = "Rented";
            Database_Id2 = "Database Id";

            Surname3 = "Surname";
            First_name3 = "First name";
            YB3 = "YB";
            S3 = "S";
            Start3 = "Start";
            Finish3 = "Finish";
            Time3 = "Time";
            Classifier3 = "Classifier";
            Chip3 = "Chip";
            Rented3 = "Rented";
            Database_Id3 = "Database Id";

            dummy = "(may be more) ...";
        }

        public override void LoadBasics(int bibno, string firstname, string surname, string gender, string country, int clubno, string clubname, string YOB, string ltext1, string ltext2, string ltext3)
        {
            Stno = bibno.ToString();
            Rented1 = "O";           // Assume not rented
            First_name1 = firstname;
            Surname1 = surname;
            S1 = gender;
            Nat = country;
            // SICard = csvr[int.Parse(textBox8.Text)-1];
            Club_no = clubno.ToString();
            City = " ";
            Cl_name = clubname;
            YB1 = YOB;
            this.Text1 = ltext1;
            this.Text2 = ltext2;
            this.Text3 = ltext3;
        }

        public override void LoadSpecifics(int offset, string sicard, string e, bool rental)
        {
            if (rental == true && this.Rented1 != "X")
                this.Rented1 = "X";

            this.Chip1 = sicard;

            Surname2 = Surname1;
            First_name2 = First_name1;
            YB2 = YB1;
            S2 = S1;
            Chip2 = Chip1;
            Rented2 = Rented1;

            if (this.Short == "LA")
            {
                Surname3 = Surname1;
                First_name3 = First_name1;
                YB3 = YB1;
                S3 = S1;
                Chip3 = Chip1;
                Rented3 = Rented1;
            }
        }

        public override string Short
        {
            get { return _short; }
            set { _short = value; }
        }


    }

    [DelimitedRecord(",")]
    class OE2003_Data : SPORTSoftwareData
    {
        public string stno;
        public string chip1;
        public string database;
        public string Surname;
        public string First_Name;
        public string YB;
        public string S;
        public string Block;
        public string nc;
        public string Start;
        public string Finish;
        public string Time;
        public string Classifier;
        public string Club_no;
        public string Cl_name;
        public string Cl_city;
        public string Nat;
        public string Cl__no;
        public string _short;
        public string Long;
        public string Num1;
        public string Num2;
        public string Num3;
        public string text1;
        public string text2;
        public string text3;
        public string Name;
        public string Street;
        public string Line2;
        public string Zip;
        public string City;
        public string phone;
        public string Fax;
        public string Email;
        public string Id_Club;
        public string rented;
        public string start_fee;
        public string paid;

        public override void CreateHeader()
        {
            stno = "stno";
            chip1 = "chip";
            database = "database id";
            Surname = "Surname";
            First_Name = "First Name";
            YB = "YB";
            S = "S";
            Block = "Block";
            nc = "nc";
            Start = "Start";
            Finish = "Finish";
            Time = "Time";
            Classifier = "Classifier";

            Club_no = "Club no";
            Cl_name = "Cl.name";
            Cl_city = "Cl_city";
            Nat = "Nat";
            Cl__no = "Cl. no";
            _short = "Short";
            Long = "Long";
            Num1 = "Num1";
            Num2 = "Num 2";
            Num3 = "Num3";
            text1 = "text1";
            text2 = "text2";
            text3 = "text3";
            Name = "Adr Name";
            Street = "Street";
            Line2 = "Line 2";
            Zip = "Zip";
            City = "City";
            phone = "phone";
            Fax = "Fax";
            Email = "Email";
            Id_Club = "Id/Club";
            rented = "rented";
            start_fee = "start fee";
            paid = "paid";
        }
        public override void LoadBasics(int bibno, string firstname, string surname, string gender, string country, int clubno, string clubname, string YOB, string ltext1, string ltext2, string ltext3)
        {
            stno = bibno.ToString();
            rented = "O";           // Assume not rented
            First_Name = firstname;
            Surname = surname;
            S = gender;
            Nat = country;
            // SICard = csvr[int.Parse(textBox8.Text)-1];
            Club_no = clubno.ToString();
            Cl_city = "";
            Cl_name = clubname;
            YB = YOB;
            this.text1 = ltext1;
            this.text2 = ltext2;
            this.text3 = ltext3;
        }
        /// <summary>
        ///  offset and e are not used
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="sicard"></param>
        /// <param name="e"></param>
        /// <param name="rental"></param>
        public override void LoadSpecifics(int offset, string sicard, string e, bool rental)
        {
            if (rental == true && this.rented != "X")
                this.rented = "X";

            this.chip1 = sicard;
        }
        public override string Short
        {
            get { return _short; }
            set { _short = value; }
        }
    }

    [DelimitedRecord(",")]
    class MT2003_Data : SPORTSoftwareData
    {
        public string stno;
        public string chip1;
        public string chip2;
        public string chip3;
        public string chip4;
        public string chip5;
        public string chip6;
        public string database;
        public string Surname;
        public string First_Name;
        public string YB;
        public string S;
        public string Block1;
        public string Block2;
        public string Block3;
        public string Block4;
        public string Block5;
        public string Block6;
        public string E1;
        public string E2;
        public string E3;
        public string E4;
        public string E5;
        public string E6;
        public string nc1;
        public string Start1;
        public string Finish1;
        public string Time1;
        public string Classifier1;
        public string nc2;
        public string Start2;
        public string Finish2;
        public string Time2;
        public string Classifier2;
        public string nc3;
        public string Start3;
        public string Finish3;
        public string Time3;
        public string Classifier3;
        public string nc4;
        public string Start4;
        public string Finish4;
        public string Time4;
        public string Classifier4;
        public string nc5;
        public string Start5;
        public string Finish5;
        public string Time5;
        public string Classifier5;
        public string nc6;
        public string Start6;
        public string Finish6;
        public string Time6;
        public string Classifier6;
        public string Club_no;
        public string Cl_name;
        public string Cl_city;
        public string Nat;
        public string Cl__no;
        public string _short;
        public string Long;
        public string Num1;
        public string Num2;
        public string Num3;
        public string text1;
        public string text2;
        public string text3;
        public string Name;
        public string Street;
        public string Line2;
        public string Zip;
        public string City;
        public string phone;
        public string Fax;
        public string Email;
        public string Id_Club;
        public string rented;
        public string start_fee;
        public string paid;

        public override void CreateHeader()
        {
            stno = "stno";
            chip1 = "chip1";
            chip2 = "chip2";
            chip3 = "chip3";
            chip4 = "chip4";
            chip5 = "chip5";
            chip6 = "chip6";
            database = "database id";
            Surname = "Surname";
            First_Name = "First Name";
            YB = "YB";
            S = "S";
            Block1 = "Block1";
            Block2 = "Block2";
            Block3 = "Block3";
            Block4 = "Block4";
            Block5 = "Block5";
            Block6 = "Block6";
            E1 = "E1";
            E2 = "E2";
            E3 = "E3";
            E4 = "E4";
            E5 = "E5";
            E6 = "E6";
            nc1 = "nc1";
            Start1 = "Start1";
            Finish1 = "Finish1";
            Time1 = "Time1";
            Classifier1 = "Classifier1";
            nc2 = "nc2";
            Start2 = "Start2";
            Finish2 = "Finish2";
            Time2 = "Time2";
            Classifier2 = "Classifier2";
            nc3 = "nc3";
            Start3 = "Start3";
            Finish3 = "Finish3";
            Time3 = "Time3";
            Classifier3 = "Classifier3";
            nc4 = "nc4";
            Start4 = "Start4";
            Finish4 = "Finish4";
            Time4 = "Time4";
            Classifier4 = "Classifier4";
            nc5 = "nc5";
            Start5 = "Start5";
            Finish5 = "Finish5";
            Time5 = "Time5";
            Classifier5 = "Classifier5";
            nc6 = "nc6";
            Start6 = "Start6";
            Finish6 = "Finish6";
            Time6 = "Time6";
            Classifier6 = "Classifier6";
            Club_no = "Club no";
            Cl_name = "Cl.name";
            Cl_city = "Cl_city";
            Nat = "Nat";
            Cl__no = "Cl. no";
            Short = "Short";
            Long = "Long";
            Num1 = "Num1";
            Num2 = "Num 2";
            Num3 = "Num3";
            text1 = "text1";
            text2 = "text2";
            text3 = "text3";
            Name = "Name";
            Street = "Street";
            Line2 = "Line 2";
            Zip = "Zip";
            City = "City";
            phone = "phone";
            Fax = "Fax";
            Email = "Email";
            Id_Club = "Id/Club";
            rented = "rented";
            start_fee = "start fee";
            paid = "paid";

        }
        public override void LoadBasics(int bibno, string firstname, string surname, string gender, string country, int clubno, string clubname, string YOB, string ltext1, string ltext2, string ltext3)
        {
            stno = bibno.ToString();
            Num1 = "0";
            Num2 = "0";
            Num3 = "0";
            rented = "O";           // Assume not rented
            First_Name = firstname;
            Surname = surname;
            S = gender;
            // SICard = csvr[int.Parse(textBox8.Text)-1];
            Club_no = clubno.ToString();
            Cl_city = string.Format("({0})", country);       // EST20110929

            Nat = country;      // EST20110929
            Cl_name = clubname;
            YB = YOB;
            E1 = E2 = E3 = E4 = E5 = E6 = "0";
            this.text1 = ltext1;
            this.text2 = ltext2;
            this.text3 = ltext3;
        }
        public override void LoadSpecifics(int offset, string sicard, string e, bool rental)
        {
            if (rental == true && this.rented != "X")
                this.rented = "X";

            switch (offset)
            {
                case 0:
                    this.chip1 = sicard;
                    this.E1 = e;
                    break;

                case 1:
                    this.chip2 = sicard;
                    this.E2 = e;
                    break;

                case 2:
                    this.chip3 = sicard;
                    this.E3 = e;
                    break;

                case 3:
                    this.chip4 = sicard;
                    this.E4 = e;
                    break;

                case 4:
                    this.chip5 = sicard;
                    this.E5 = e;
                    break;

                case 5:
                    this.chip6 = sicard;
                    this.E6 = e;
                    break;
            }
        }
        public override string Short
        {
            get { return _short; }
            set { _short = value; }
        }
    }

    struct PerClass
    {
        public string shortClassName;
        public bool active;
        public bool participating;
    }


    public class RaceData
    {
        public void Save(string name)
        {
            XmlSerializer ser = new XmlSerializer(typeof(RaceData));
            TextWriter writer = new StreamWriter(name);
            ser.Serialize(writer, this);
            writer.Close();
            writer.Dispose();
        }
        public static RaceData Load(string name)
        {
            XmlSerializer ser = new XmlSerializer(typeof(RaceData));
            TextReader reader = new StreamReader(name);
            RaceData r = (RaceData) ser.Deserialize(reader);
            reader.Close();
            reader.Dispose();
            return r;
        }

        public enum TextAction
        {
            LeaveEmpty = 0,
            ConvYesToStar = 1,
            CopyData = 2
        }

        [System.Xml.Serialization.XmlIgnoreAttribute()]
        public bool DirtyFlag;

        public string Surname;
        public string Firstname;
        public string Gender;
        public string Country;
        public string SICard;
        public string Club;
        public string YearBorn;

        public string DataFile;
        public string ClassFile;
        public string OutputFile;
        public string RentalsFile;

        public int NumberRaces;
        public string Race1;
        public string Race2;
        public string Race3;
        public string Race4;
        public string Race5;
        public string Race6;
        public string Text1;
        public TextAction Text1Action;
        public string Text2;
        public TextAction Text2Action;
        public string Text3;
        public TextAction Text3Action;

        public int FirstBib;
        public bool ExtractClubAbbrev;
        public bool ExtractCountryAbbrev;

        public bool ChaseSprint;
        public int RaceFormat;
    }
}
